package com.jt.common.aspect;

import com.alibaba.fastjson.JSON;
import com.jt.common.util.IpUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Enumeration;

/**
 * 参数拦截器
 *
 * @author: yangming
 * @date : 2016-09-22 12:37
 */
@Order(999) // 小的先执行
@Aspect
@Component
public class LogRequestAspect {

	public Logger logger = LoggerFactory.getLogger(this.getClass());
	ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();

	@Pointcut("execution(public * com.jt.*.rest.*..*(..))")
	public void printRequestLog() {
	}

	@Before("printRequestLog()")
	public void doBefore(JoinPoint jionPoint) {
		try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			HttpServletRequest request = attributes.getRequest();
			Long aop_start = System.currentTimeMillis();
			threadLocal.set(aop_start);
			StringBuilder builder = new StringBuilder();
			builder.append("\n当前请求接口统计记录 URI: " + request.getRequestURI() + "  参数如下: \n");
			builder.append("REQUEST_UNIQUE : " + request.getHeader("ruid") + "\n");
			builder.append("HTTP_METHOD : " + request.getMethod() + "\n");
			Enumeration headerNames = request.getHeaderNames();
			StringBuilder buiHeader = new StringBuilder();
			while (headerNames.hasMoreElements()) {
				String key = (String) headerNames.nextElement();
				String value = request.getHeader(key);
				buiHeader.append(key + "=" + value + " ");
			}
			builder.append("HTTP_HEADERS : " + buiHeader.toString() + "\n");
			builder.append("IP : " + IpUtil.getIpAddress(request) + "\n");
			builder.append("CLASS_METHOD : " + jionPoint.getSignature().getDeclaringTypeName() + "."
					+ jionPoint.getSignature().getName() + "\n");
			Object[] paramValues = jionPoint.getArgs();
			String[] paramNames = ((CodeSignature) jionPoint.getSignature()).getParameterNames();
			String[] paramNameValues = new String[paramNames.length];
			for (int i = 0; i < paramNames.length; i++) {
				if ("request".equals(paramNames[i]) || "response".equals(paramNames[i])) {
					continue;
				}
				paramNameValues[i] = paramNames[i] + " = " + JSON.toJSONString(paramValues[i]);
			}
			builder.append("PARAMS : " + Arrays.toString(paramNameValues) + "\n");
			builder.append("TimeStamp : " + aop_start);
			logger.info(builder.toString());
		} catch (Exception e) {
			logger.info(e.getMessage(), e);
		}
	}

	@After("printRequestLog()")
	public void doAfter() throws Throwable {
		try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			HttpServletRequest request = attributes.getRequest();
			Long timestamp = System.currentTimeMillis();
			String request_unique = request.getHeader("ruid");
			Long executeTime = timestamp - threadLocal.get();
			if (executeTime > 3000) {
				logger.warn("当前请求接口耗时统计记录:URI[ {} ] ,more than 3s,  REQUEST_UNIQUE [{}] TimeStamp [{}] ,executeTime [{}ms]",
						request.getRequestURI(), request_unique, timestamp, executeTime);
			} else {
				logger.debug("当前请求接口耗时统计记录:URI[ {} ]  REQUEST_UNIQUE [{}] TimeStamp [{}]  executeTime [{}ms]",
						request.getRequestURI(), request_unique, timestamp, executeTime);
			}
			logger.info("接口结束时间:"+ LocalDateTime.now() +",当前请求接口耗时:"+executeTime+"ms");

		} catch (Exception e) {
			logger.info(e.getMessage(), e);
		}
	}

}